class InteractiveDominos

	
	
	include DominoBestMove
	
	SCORER = 2
	EMPTY_TABLE = ["*"]
	
	def initialize(n, own_mode = false, debug = false)
	 
		@num = n
		@quit = false
		@players = []
		@num_players = 0
		@num_controlled_players
		@board = Board.new
		@pool = Pool.new @num
		@own_mode = own_mode
	   
	end
	
	def begin
	  init_lookup_table(@num)
		intro
		play
		puts "\n* GAME OVER *\n"
		@players.each{|p| p.print_player}
		nil
	end
	
	def intro
		puts "\n\nYou are playing dominos"
		$logger.debug "Intro to new game!"
		
		@players << Player.new("Zach", @pool, @board, true)
		@players << Player.new("Molly", @pool, @board, !@own_mode)
		
		puts "\nLazy way, just generated the players for you\n"
		if @own_mode
		  puts "are you first?"
      inp = gets.chomp
      @current_player = (inp == 'n') ? @players[1] : @players.first
			puts "enter your hand:"
			make_hand
		else
			@players.each{|p| p.draw_hand(@num)}
			@current_player = @players.first
		end
	end
	
	def play
	
		while !is_game_over? do
			
			if @current_player.controlled
			
				needs_input = true
				while needs_input do 
				  
				  puts "#{@current_player.name} TURN"
				  $logger.debug "#{@current_player.name} TURN"
					
					puts "Hand #{@current_player.hand.to_s}"
					puts "Valids #{@current_player.legal_plays.to_s}"
					
					@current_player.print_player
					@current_player.board.print_board
					@current_player.pool.print_pool
					$logger.debug "\n"
					
					input = gets.split(" ")
			
					if input[0] == "best"
					  h_size = input[1].to_i
					  agg = (input.size > 2) ? (input[2].to_s == "-a") : false
					  max_dep = (input.size > 3) ? (input[3].to_i) : 4
						puts "finding best move this could take a long....while, opponent hand size: #{h_size} aggressor: #{agg}"
						t = find_best_move(@players, @current_player, h_size, agg, max_dep)
						puts "\nFOUND THE BEST ITS!!"
						puts "play #{t.last_played} for min of #{t.points}"
					elsif input[0] == "debug"
						$debug = !$debug
						$debug ? ($logger.level = Logger::DEBUG) : ($logger.level = Logger::INFO)
					elsif input[0] == "show"
						@board.print_board
					elsif input[0] == "pool"
						puts "#{@pool.print_pool}"
					elsif input[0] == "exit"
						@quit = true
					elsif input[0] == "draw"
						@current_player.draw
					elsif input[0] == "fdraw"
						puts "enter what you drew"
						make_hand(@current_player)
					elsif input[0] == "pass"
					  puts "passing on this turn..."
					  needs_input = false
					elsif input.size == 2 and !@board.game_started?
						domino = Domino.new input[0].to_i, input[1].to_i
						dominee = EMPTY_TABLE
						needs_input = !validate_input(domino, dominee)
					elsif input.size == 4
						domino = Domino.new input[0].to_i, input[1].to_i #the one you want to play
						dominee = Domino.new input[2].to_i, input[3].to_i #the one you want to play on
						needs_input = !validate_input(domino, dominee)
					elsif input.size == 5
            domino = Domino.new input[0].to_i, input[1].to_i #the one you want to play
            dominee = Domino.new input[2].to_i, input[3].to_i #the one you want to play on
            if input[4].to_s == 's'
              dominee.spinner = true
            end
            needs_input = !validate_input(domino, dominee)
					else
						puts "unknown entry play a domino by entering the domino you want to play followed by the domino you wish to play on. ex: 2 3 4 3"
					end
				
					needs_input = needs_input && !is_game_over?
				end
			
				succ = @current_player.play_domino(domino, dominee) if domino && dominee
		
				if succ
					if @board.sum_ends % SCORER == 0
						@current_player.points += @board.sum_ends
					end
					next_player
				elsif input[0] == 'pass'
				  next_player
				else
				  puts "your play was rejected for some reason try again."
				end
			
			else
				
				p = @players.first #all moves are tracked through the main player's board in own_mode
				
				puts  "what did the enemy play???"
				puts "scoring tiles #{p.board.scoring_tiles(p.pool.dominos)}"
        puts "black list: #{p.board.black_list}"
				
				inp = gets.split(" ")
				
				if inp.size == 2
				  domino = Domino.new inp[0].to_i, inp[1].to_i
				  dominee = EMPTY_TABLE
				elsif inp.size == 4
				  domino = Domino.new inp[0].to_i, inp[1].to_i
				  dominee = Domino.new inp[2].to_i, inp[3].to_i
				elsif inp.size == 5
				  domino = Domino.new inp[0].to_i, inp[1].to_i
          dominee = Domino.new inp[2].to_i, inp[3].to_i
          if inp[4].to_s == 's'
              dominee.spinner = true
          end
        else
          puts "need error correction here...just passing...!"
				end
				
				p.play_domino(domino, dominee, true) if domino && dominee 
				
				next_player
			end
		
		end
	end
	
	private
	
	def next_player
		i = @players.index @current_player
		@current_player = @players[(i + 1) % @players.size]
	end
	
	def validate_input(d1, d2)
		true
	end
	
	def others_can_play?
		a_player = @players.inject(false) do |memo, p|
			if p == @current_player
				memo || false
			else
				memo || !p.legal_plays.empty?
			end
		end
		a_player
	end
	
	def previous_guy_won?
		i = @players.index @current_player
		prev_guy = @players[i-1]
		prev_guy.dominos.empty?
	end
	
	def is_game_over?
	  
		#cases: 
		#previous guy ran out of dominos
		#no other players can play and pool is empty
		#someone quit
		if !@own_mode
			gameover = previous_guy_won?
			gameover = (gameover || (!others_can_play? and @pool.empty?))
			gameover = gameover || @quit
			gameover
		else
			#@current_player.hand.dominos.empty? || @quit
			@quit
		end
		
	end
	
	def make_hand(player = nil)
		p = player || @players.first
		$logger.debug "Adding bones to #{p.name}'s hand" 
		n = true
		while(n)
			inp = gets.split(" ")
			
			if inp.size == 2
				d = Domino.new inp[0].to_i, inp[1].to_i
				p.force_draw d
				$logger.debug "Adding #{d}"
			else
				n = false
			end
		end
		$logger.debug "\n"
	end
	
end

class Integer
	def round_to_five
		dif = self % 5
		if dif > 2 	#round up
		self + (5-dif)
		else		#round down
		self - dif
		end
	end
end

class Array
	def duplicate
		ary = []
		self.each do |i|
			ary << i.dup
		end
		ary
	end
end